﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 场馆订单自动取消定时任务
    /// </summary>
    [ReccuringJobCron("0 0/5 * * * ?")]
    public class VenueOrderCancelHangfireService : IHangfireService
    {
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly ISiteOrderRepository _siteOrderRepository;
        private readonly ISiteOrderDetailRepository _siteOrderDetailRepository;
        private readonly ISitePriceListRepository _sitePriceListRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public VenueOrderCancelHangfireService(
            ISiteOrderRepository siteOrderRepository,
            ISiteOrderDetailRepository siteOrderDetailRepository,
            ISitePriceListRepository sitePriceListRepository,
            IUnitOfWorkManager unitOfWorkManager)
        {
            _siteOrderRepository = siteOrderRepository;
            _siteOrderDetailRepository = siteOrderDetailRepository;
            _sitePriceListRepository = sitePriceListRepository;
            _unitOfWorkManager = unitOfWorkManager;
        }

        /// <summary>
        /// 执行
        /// </summary>
        public async Task ExecuteAsync()
        {
            var datetime = DateTimeOffset.Now.DateTime.AddMinutes(-5);
            var orderIdList = await _siteOrderRepository.AsNoTracking()
                .Where(m => m.SO_State == VenueOrderStateEnum.NoPay && m.CreateTime < datetime)
                .Select(m => m.ID)
                .Take(50).ToListAsync();
            if (orderIdList.Any())
            {
                var queryable = from detail in _siteOrderDetailRepository.AsNoTracking()
                                join price in _sitePriceListRepository.AsNoTracking()
                                on detail.SitePriceListID equals price.ID
                                where orderIdList.Contains(detail.SiteOrderID)
                                select price.ID;
                var priceIdList = await queryable.ToListAsync();
                using (var uow = _unitOfWorkManager.Begin())
                {
                    var orderBuilder = await _siteOrderRepository.UpdatePartialAsync();
                    await orderBuilder.Set(m => m.SO_State, VenueOrderStateEnum.Completed)
                        .Set(m => m.SO_CancelRole, OrderCancelTypeEnum.Platform)
                        .Set(m => m.SO_CancelTime, DateTimeOffset.Now)
                        .Set(m => m.SO_CancelRemark, "5分钟未支付自动取消")
                        .Where(m => orderIdList.Contains(m.ID))
                        .ExecuteAsync();
                    var priceBuilder = await _sitePriceListRepository.UpdatePartialAsync();
                    await priceBuilder.Set(m => m.SPL_State, VenuePriceStateEnum.CanChoice)
                        .Where(m => priceIdList.Contains(m.ID))
                        .ExecuteAsync();
                    await uow.CompleteAsync();
                }
            }
        }
    }
}
